/**
 * 
 */
package co.edu.uniandes.distribuidos.security;

import java.io.File;
import java.io.IOException;
import java.security.cert.X509Certificate;

import net.jxta.impl.membership.pse.FileKeyStoreManager;
import net.jxta.impl.protocol.PSEConfigAdv;
import net.jxta.peergroup.PeerGroup;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.platform.NetworkManager;
import net.jxta.protocol.ConfigParams;
import co.edu.uniandes.distribuidos.config.AppConfig;
import co.edu.uniandes.distribuidos.security.exception.SecurityServicesException;

/**
 * @author Andrey
 *
 */
public class SecurityServices {
	
	
	private FileKeyStoreManager MyFileKeyStoreManager;
	private File keyStoreFile;
	private static SecurityServices instance;
	public final static String password = "password1";
	public final static String keyStorePassword = "keyStorePassword";
	public final static String PlatformConfig ="PlatformConfig";
	public PeerGroup netPeerGroup = null;
	
	static{
		instance=new SecurityServices();
	}
	
	private SecurityServices(){
		
	}

	public void createKeyStore() throws SecurityServicesException{
		
		// preparing data
		String keyStoreFileName = "jxta.jks";
		
		String keyStoreProvider = "JXTA"; 
		keyStoreFile = new File(AppConfig.getInstance().getKeystoreDirectory() + 
				File.separator+ keyStoreFileName);
		
		try {
			MyFileKeyStoreManager = new FileKeyStoreManager(
					null, keyStoreProvider, keyStoreFile);
			if(!keyStoreFile.exists()){
				MyFileKeyStoreManager.createKeyStore(keyStorePassword.toCharArray()); 
			}
			// checking initialization
			if (MyFileKeyStoreManager.isInitialized()) { 
				System.out.println("Keystore initialized successfully"); 
			} else { 
				System.out.println("Keystore NOT initialized successfully");
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SecurityServicesException(e);
		} 
	}

	
	public void createCertificate(NetworkManager manager) throws SecurityServicesException{
	
		// Retrieving the network configurator
		try {
			NetworkConfigurator config = manager.getConfigurator();
			
			//if (pc.delete()) {
		        // Create a new configuration with a new name, principal, and pass
				// Setting the key store location
				config.setKeyStoreLocation(keyStoreFile.toURI()); 
				// Setting the name to be used for the X500 principal
				config.setPrincipal(keyStorePassword); 
				// Setting a password for encrypting the private key that will be
				// created as part of the X.509 automatic certificate creation
				config.setPassword(password); 
				// Saving the configuration, which will trigger the X.509 certificate creation
				config.save(); 
				 
//		      } else {
//		    	  throw new SecurityServicesException("Error creando el certificado");
//		      }
		 
			// Trying to retrieve the X.509 certificate from the configurator
			X509Certificate myX509Certificate = config.getCertificate(); 
			config.setPeerID(manager.getPeerID());
			config.save(); 
			if (myX509Certificate==null){
				System.out.println("certificado no actualizado");
			}
				viewCertificate(manager);
		} catch (Exception e) {
			e.printStackTrace();
			throw new SecurityServicesException(e);
		} 
		
	}
	
	private void viewCertificate(NetworkManager manager) throws IOException{
		// Retrieving the configuration parameters
		NetworkConfigurator configurator = manager.getConfigurator();
		ConfigParams configParams = configurator.getPlatformConfig();
		// Retrieving the PSE configuration advertisement
		PSEConfigAdv MyPSEConfigAdv = (PSEConfigAdv)configParams.
			getSvcConfigAdvertisement(PeerGroup.membershipClassID); 
		// Retrieving the X.509 certificate
		X509Certificate certificate = MyPSEConfigAdv.getCertificate(); 
		if(certificate!=null)
		System.out.println(certificate.toString());
	}
	
	public static SecurityServices getInstance(){
		return instance;
	}

	public PeerGroup getNetPeerGroup() {
		return netPeerGroup;
	}

	public void setNetPeerGroup(PeerGroup netPeerGroup) {
		this.netPeerGroup = netPeerGroup;
	}
}
